---
title: "JDBC 处理时间类型、时区问题"
date: 2020-6-30
categories:
- java
tags:
---

<div id="content">
<p>
调用堆栈：
</p>
<p>
&lt;init&gt;:111, Timestamp (java.sql)
createFromTimestamp:91, SqlTimestampValueFactory (com.mysql.cj.core.io)
createFromTimestamp:38, SqlTimestampValueFactory (com.mysql.cj.core.io)
createFromTimestamp:54, BaseDecoratingValueFactory (com.mysql.cj.core.io)
createFromTimestamp:54, BaseDecoratingValueFactory (com.mysql.cj.core.io)
decodeTimestamp:177, MysqlTextValueDecoder (com.mysql.cj.core.io)
decodeAndCreateReturnValue:67, AbstractResultsetRow (com.mysql.cj.mysqla.result)
getValueFromBytes:225, AbstractResultsetRow (com.mysql.cj.mysqla.result)
getValue:84, ByteArrayRow (com.mysql.cj.mysqla.result)
getNonStringValueFromRow:632, ResultSetImpl (com.mysql.cj.jdbc.result)
getDateOrTimestampValueFromRow:645, ResultSetImpl (com.mysql.cj.jdbc.result)
getTimestamp:941, ResultSetImpl (com.mysql.cj.jdbc.result)
testGet:36, MySqlDatetimeTest (db)
invoke0:-1, NativeMethodAccessorImpl (sun.reflect)
invoke:62, NativeMethodAccessorImpl (sun.reflect)
invoke:43, DelegatingMethodAccessorImpl (sun.reflect)
invoke:498, Method (java.lang.reflect)
runReflectiveCall:50, FrameworkMethod$1 (org.junit.runners.model)
run:12, ReflectiveCallable (org.junit.internal.runners.model)
invokeExplosively:47, FrameworkMethod (org.junit.runners.model)
evaluate:17, InvokeMethod (org.junit.internal.runners.statements)
runLeaf:325, ParentRunner (org.junit.runners)
runChild:78, BlockJUnit4ClassRunner (org.junit.runners)
runChild:57, BlockJUnit4ClassRunner (org.junit.runners)
run:290, ParentRunner$3 (org.junit.runners)
schedule:71, ParentRunner$1 (org.junit.runners)
runChildren:288, ParentRunner (org.junit.runners)
access$000:58, ParentRunner (org.junit.runners)
evaluate:268, ParentRunner$2 (org.junit.runners)
run:363, ParentRunner (org.junit.runners)
run:137, JUnitCore (org.junit.runner)
startRunnerWithArgs:68, JUnit4IdeaTestRunner (com.intellij.junit4)
startRunnerWithArgs:33, IdeaTestRunner$Repeater (com.intellij.rt.junit)
prepareStreamsAndStart:230, JUnitStarter (com.intellij.rt.junit)
main:58, JUnitStarter (com.intellij.rt.junit)
</p>
<p>
SqlTimestampValueFactory 构造函数接收一个TimeZone参数，而这个参数在 com/mysql/cj/jdbc/result/ResultSetImpl.java
</p>
<div class="org-src-container">
<pre class="src src-java"> <span style="font-weight: bold;">public</span> <span style="font-weight: bold;">ResultSetImpl</span>(<span style="font-weight: bold; text-decoration: underline;">ResultsetRows</span> <span style="font-weight: bold; font-style: italic;">tuples</span>, <span style="font-weight: bold; text-decoration: underline;">JdbcConnection</span> <span style="font-weight: bold; font-style: italic;">conn</span>, <span style="font-weight: bold; text-decoration: underline;">StatementImpl</span> <span style="font-weight: bold; font-style: italic;">creatorStmt</span>) <span style="font-weight: bold;">throws</span> <span style="font-weight: bold; text-decoration: underline;">SQLException</span> {
        <span style="font-weight: bold;">this</span>.connection = conn;
        <span style="font-weight: bold;">this</span>.session = conn.getSession();
        ...
        <span style="font-weight: bold;">this</span>.defaultTimestampValueFactory = decorateDateTimeValueFactory(<span style="font-weight: bold;">new</span> <span style="font-weight: bold; text-decoration: underline;">SqlTimestampValueFactory</span>(<span style="font-weight: bold;">this</span>.session.getDefaultTimeZone()),
                <span style="font-weight: bold;">this</span>.zeroDateTimeBehavior);
        ...
}
</pre>
</div>
<p>
通过这个session的API能够获取到当前连接的时区信息。但这个API是平台相关的，getSession不在DataSource接口的定义内。
</p>
</div>
<div class="status" id="postamble">
<p class="date">Date: 2020-6-30</p>
<p class="author">Author: gdme1320</p>
<p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
</div>
